package win.smartown.android.library.certificateCamera;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.List;

import win.smartown.android.library.certificateCamera.detection.NV21ToBitmap;

/**
 * 相机预览封装
 */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

    private static String TAG = "h2";

    private Camera camera;
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;

    private MediaRecorder videoRecorder;
//    private String myVideofilepath = "sdcard/myvideo.3gp";
    private NV21ToBitmap nv21tool;

    int[] attrsArray = new int[]{
            R.attr.isFront
    };
    boolean isFront;
    Size bestSize;
    int defWidth = 800;
    int defHeight = 400;
    onFrame onFrame;
    onFrameStream onFrameStream;


//    private Camera.AutoFocusCallback myAutoFocusCallback = new Camera.AutoFocusCallback() {
//        public void onAutoFocus(boolean success, Camera camera) {
//            if (success)//success表示对焦成功
//            {
//                Log.e(TAG, "onAutoFocus succeed...");
//                camera.cancelAutoFocus();//只有加上了这一句，才会自动对焦。
//                //  initCamera(mSurfaceHolder);
//                doAutoFocus();
//            } else {
//                Log.i(TAG, "onAutoFocus failed...");
//            }
//        }
//    };


//    //设置聚焦
//    private void doAutoFocus() {
//        Camera.Parameters parameters = camera.getParameters();
//        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//        camera.setParameters(parameters);
//        camera.autoFocus(new Camera.AutoFocusCallback() {
//            @Override
//            public void onAutoFocus(boolean success, Camera camera) {
//                if (success) {
//                    camera.cancelAutoFocus();// 只有加上了这一句，才会自动对焦。
//                    if (!Build.MODEL.equals("KORIDY H30")) {
//                        Camera.Parameters parameters = camera.getParameters();
//                        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 连续自动对焦
//                        camera.setParameters(parameters);
//                    } else {
//                        Camera.Parameters parameters = camera.getParameters();
//                        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//                        camera.setParameters(parameters);
//                    }
//                }
//            }
//        });
//    }


    public CameraPreview(Context context) {
        super(context);

        Log.e("k9", "init 3");

        init(null);
    }

    public CameraPreview(Context context, AttributeSet attrs) {
        super(context, attrs);
        Log.e("k9", "init 2 ");

        init(attrs);
    }

    public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        Log.e("k9", "init 1");

        init(attrs);
    }

//    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
//    public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
//        super(context, attrs, defStyleAttr, defStyleRes);
//
//        Log.e("k9", "init 0");
//        init(attrs);
//    }


    private void init(AttributeSet attrs) {
        TypedArray ta = getContext().obtainStyledAttributes(attrs, attrsArray);
        isFront = ta.getBoolean(0, false);
        ta.recycle();
        surfaceView = this;
        surfaceHolder = getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setKeepScreenOn(true);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        videoRecorder = new MediaRecorder();

        nv21tool = new NV21ToBitmap(getContext());
        Log.e("k9", "init");
    }


    public void surfaceCreated(SurfaceHolder holder) {
        int cameraType = 1;
        if (isFront) {
            cameraType = 1;
        } else {
            cameraType = 2;
        }
        camera = CameraUtils.openCamera(cameraType);

        if (camera != null) {
            try {
                camera.setPreviewDisplay(holder);
                Camera.Parameters parameters = camera.getParameters();
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

                if (cameraType == 1) {
                    camera.setDisplayOrientation(90);
                } else {
                    camera.setDisplayOrientation(0);
                }
                parameters.setRotation(0);
                //   parameters.setPreviewFormat(ImageFormat.JPEG);


                bestSize = getBestSize(parameters.getSupportedPreviewSizes());
                if (bestSize != null) {
                    parameters.setPreviewSize(bestSize.width, bestSize.height);
                    parameters.setPictureSize(bestSize.width, bestSize.height);
                } else {
                    parameters.setPreviewSize(defWidth, defHeight);
                    parameters.setPictureSize(defWidth, defHeight);
                }
                camera.setParameters(parameters);
                startPreview();
                focus();
            } catch (Exception e) {
                Log.e(TAG, "Error setting camera preview: " + e.getMessage());
                try {
                    Camera.Parameters parameters = camera.getParameters();

                    if (cameraType == 1) {
                        camera.setDisplayOrientation(90);
                    } else {
                        camera.setDisplayOrientation(0);
                    }
                    parameters.setRotation(0);
                    //    parameters.setPreviewFormat(ImageFormat.JPEG);

                    camera.setParameters(parameters);
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                    startPreview();
                    focus();
                } catch (Exception e1) {
                    e.printStackTrace();
                    camera = null;
                }
            }
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        //因为设置了固定屏幕方向，所以在实际使用中不会触发这个方法
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.e("xiong", "------surfaceDestroyed-----release");
        //回收释放资源
        release();
    }


    /**
     * Android相机的预览尺寸都是4:3或者16:9，这里遍历所有支持的预览尺寸，得到16:9的最大尺寸，保证成像清晰度
     *
     * @param sizes
     * @return 最佳尺寸
     */
    private Size getBestSize(List<Size> sizes) {
        Size bestSize = null;
        for (Size size : sizes) {
            Log.e("xiong", "w:" + size.width + "H:" + size.height);
            if ((float) size.width / (float) size.height == 16.0f / 9.0f) {
                if (bestSize == null) {
                    bestSize = size;
                } else {
                    if (size.width > bestSize.width) {
                        bestSize = size;
                    }
                }
            }
        }
        return bestSize;
    }

    /**
     * 释放资源
     */
    private void release() {
        if (camera != null) {
            camera.stopPreview();
            camera.setPreviewCallback(null);
            camera.setPreviewCallbackWithBuffer(null);
            camera.release();
            camera = null;
        }
    }


    /**
     * 开关闪光灯
     *
     * @return 闪光灯是否开启
     */
    public boolean switchFlashLight() {
        if (camera != null) {
            Camera.Parameters parameters = camera.getParameters();
            if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_OFF)) {
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                camera.setParameters(parameters);
                return true;
            } else {
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                camera.setParameters(parameters);

                return false;
            }
        }
        return false;
    }

    /**
     * 拍摄照片
     *
     * @param pictureCallback 在pictureCallback处理拍照回调
     */
    public void takePhoto(Camera.PictureCallback pictureCallback) {
        if (camera != null) {
            camera.takePicture(null, null, pictureCallback);
        }
    }

    public void startPreview() {
        if (camera != null) startPreview(previewCallback);
    }

    public void stopPreview() {
        if (camera != null) camera.stopPreview();
    }

    public static interface onFrame {
        void onBitmap(Bitmap bitmap);
    }

    public static interface onFrameStream {
        void onStream(byte[] bytes);
    }


    public void setOnFrameListener(onFrame listener) {
        onFrame = listener;
    }

    private class PreviewCallback implements Camera.PreviewCallback {


        @Override
        public void onPreviewFrame(final byte[] data, Camera camera) {
            // currentTime = System.currentTimeMillis();
            camera.addCallbackBuffer(data);
            Size size = camera.getParameters().getPreviewSize();
            //  byte[] bytes= rotateYUV420Degree90(data,size.width,size.height);
            try {

                Bitmap bmp;
                byte[] frontdata;
                if (isFront) {


                    Log.e("h2_00008", "size.width = " + size.width);
                    Log.e("h2_00008", "size.height = " + size.height);

                    frontdata = rotateYUV420Degree270(data, size.width, size.height);

                    Log.e("h2_00008", "frontdata.length = " + frontdata.length);
                    Log.e("h2_00008", "data.length = " + data.length);


                    if(onFrameStream!=null){
//                        onFrameStream.onStream(frontdata);
                        onFrameStream.onStream(data);
                        return;
                    }

                    Log.e("h2_00008", "nv21ToBitmap(frontdata, size.height, size.width)");
                    bmp = nv21tool.nv21ToBitmap(frontdata, size.height, size.width);
                } else {
                    bmp = nv21tool.nv21ToBitmap(data, size.width, size.height);
                }
                if (onFrame != null) {
                    onFrame.onBitmap(bmp);
                }

            } catch (Exception ex) {
                Log.e("Sys", "Error:" + ex.getMessage());
            }
        }
    }


    private byte[] rotateYUV420Degree270(byte[] data, int imageWidth, int imageHeight) {
        byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
        // Rotate the Y luma
        int i = 0;
        for (int x = imageWidth - 1; x >= 0; x--) {
            for (int y = 0; y < imageHeight; y++) {
                yuv[i] = data[y * imageWidth + x];
                i++;
            }
        }
        // Rotate the U and V color components  	i = imageWidth*imageHeight;
        for (int x = imageWidth - 1; x > 0; x = x - 2) {
            for (int y = 0; y < imageHeight / 2; y++) {
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
                i++;
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
                i++;
            }
        }
        return yuv;
    }


    PreviewCallback previewCallback = new PreviewCallback();


    private void startPreview(Camera.PreviewCallback cb) {
        if (camera != null) {

            camera.setPreviewCallback(cb);
            camera.startPreview();
            Log.d("xiong", "startPreview() called");

        }
    }


    /**
     * 对焦，在CameraActivity中触摸对焦
     */


    public static interface onFocusSuccess {
        void onFocusSuccess();

    }

    onFocusSuccess onFocusSuccesslistener;


    public void setonFocusSuccessListener(onFocusSuccess listener) {
        onFocusSuccesslistener = listener;
    }


    public void focus() {
        if (camera != null) {
            // camera.autoFocus(null);

            try {
                camera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        if (success) {
                            onFocusSuccesslistener.onFocusSuccess();
                        } else {

                        }
                    }
                });
            } catch (Exception e) {
                Log.e("xiong", e.getMessage());
            }

        }
    }


}
